home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / util / misc / cookie21.lha / Cookie / cookie.c < prev    next >
C/C++ Source or Header  |  1995-08-22  |  4KB  |  181 lines

  1. /* cookie - print out an entry from the sayings file
  2.  * by Karl Lehenbauer (karl@sugar.uu.net, uunet!sugar!karl)
  3.  *  cookie.c  1.1  1/12/89
  4.  *            ^^^^^^^^^^^^
  5.  *            obsolete; see below
  6.  */
  7.  
  8. /*
  9.  * 1995-04-19 [J÷G] changed the random number generation a bit
  10.  *                  didn't bump revision though
  11.  *
  12.  * 1995-04-27 [J÷G] different cookie file format now; there are
  13.  *                  as many cookies now as there are entries in
  14.  *                  the hash file
  15.  *                  version bumped to cookie 2.0 due to the changed
  16.  *                  format and the lexified 'cookhash'
  17.  *
  18.  * 1995-08-22 [J÷G] still, the random number generation/seeding/
  19.  *                  ranging wasn't good enough. Incorporated
  20.  *                  a PD version of the R250 algorithm, which seems
  21.  *                  to work just fine.
  22.  *                  Cookie version 2, revision 1.
  23.  *
  24.  */
  25.  
  26. #include <math.h>
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <time.h>
  30.  
  31. #include <proto/exec.h>
  32.  
  33. #include "r250.h"
  34.  
  35. #include "cookie.h"
  36.  
  37. #define ENTSIZE 7L
  38. #define METACHAR '%'
  39. #define YES 1
  40. #define NO 0
  41.  
  42. /*
  43.  * char *sccs_id = "@(#) fortune cookie program 1.1 1/12/89 by K. Lehenbauer";
  44.  */
  45.  
  46. static char verstring[] = "$" "VER: cookie 2.1 (22.8.95) "
  47.                             "Lehenbauer/Kirchwitz/Grahn";
  48.  
  49. char *cookiename = COOKIEFILE;
  50. char *hashname = HASHFILE;
  51.  
  52. #ifdef ORIGINALRAND
  53. /* really_random - insure a good random return for a range, unlike an arbitrary
  54.  * random() % n, thanks to Ken Arnold, Unix Review, October 1987
  55.  * ...likely needs a little hacking to run under Berkely
  56.  */
  57. #define RANDOM_RANGE ((1 << 15) - 1)
  58. static int really_random(int my_range)
  59. {
  60.     int max_multiple, rnum;
  61.  
  62.     max_multiple = RANDOM_RANGE / my_range;
  63.     max_multiple *= my_range;
  64.     while ((rnum = rand()) >= max_multiple)
  65.         continue;
  66.     return(rnum % my_range);
  67. }
  68. #endif /*ORIGINALRAND*/
  69.  
  70. main(int argc,char *argv[])
  71. {
  72.     int nentries, oneiwant, c, sawmeta = 0;
  73.     FILE *hashf, *cookief;
  74.     long cookiepos;
  75.  
  76.     /* if we got exactly three arguments, use the cookie and hash
  77.      * files specified
  78.      */
  79.     if (argc == 3)
  80.     {
  81.         cookiename = argv[1];
  82.         hashname = argv[2];
  83.     }
  84.     /* otherwise if argc isn't one (no arguments, specifying the
  85.      * default cookie file), barf
  86.      */
  87.     else if (argc != 1)
  88.     {
  89.         fputs("usage: cookie cookiefile hashfile\n",stderr);
  90.         exit(1);
  91.     }
  92.  
  93.     /* open the cookie file for read */
  94.     if ((cookief = fopen(cookiename,"r")) == NULL)
  95.     {
  96.         perror(cookiename);
  97.         exit(2);
  98.     }
  99.  
  100.     /* open the hash file for read */
  101.     if ((hashf = fopen(hashname,"r")) == NULL)
  102.     {
  103.         perror(hashname);
  104.         exit(2);
  105.     }
  106.  
  107.     /* compute number of cookie addresses in the hash file by
  108.      * dividing the file length by the size of a cookie address
  109.      * and subtract 1 (after the last %% is no cookie)
  110.      * Yes there is! [J÷G]
  111.      *
  112.      */
  113.     if (fseek(hashf,0L,2) != 0)
  114.     {
  115.         perror(hashname);
  116.         exit(3);
  117.     }
  118.     nentries = (ftell(hashf) / ENTSIZE) - 1 + 1;
  119.  
  120.     /*
  121.      * I Left the original (pre-2.1) random code in
  122.      * for compeleness. Define ORIGINALRAND if
  123.      * you want it.
  124.      *
  125.      */
  126. #ifdef ORIGINALRAND
  127.     /* seed the random number generator with time in seconds plus
  128.      * the program's process ID - it yields a pretty good seed
  129.      * again, thanks to Ken Arnold
  130.      * AMK: FindTask()
  131.      */
  132.     srand((long)FindTask(NULL) + time(NULL));
  133.  
  134.     /*
  135.      * AMK: get a dummy value
  136.      */
  137.     rand();
  138.  
  139. #if 1
  140.     /* generate a not really random number */
  141.     /* this was the original unix s5r4 version, too sophisticated */
  142.        oneiwant = really_random(nentries);
  143. #else
  144.     /* this is version seems to be random enough ;-) (AMK) */
  145.     oneiwant = rand() % nentries;
  146. #endif
  147. #else /* ORIGINALRAND */
  148.     r250_init((unsigned short)FindTask(NULL) ^ (unsigned short)time(NULL));
  149.  
  150.     oneiwant = r250n(nentries);
  151. #endif /* ORIGINALRAND */
  152.  
  153.     /* locate the one I want in the hash file and read the
  154.      * address found there
  155.      */
  156.     fseek(hashf,(long)oneiwant * ENTSIZE, 0);
  157.     fscanf(hashf,"%lx",&cookiepos);
  158.  
  159.     /* seek cookie file to cookie starting at address read from hash */
  160.     fseek(cookief,cookiepos,0);
  161.  
  162.     /* get characters from the cookie file and write them out
  163.      * until finding the end-of-fortune sequence, '%%'
  164.      */
  165.     while ((c = fgetc(cookief)) != EOF && sawmeta < 2)
  166.     {
  167.         if (c != METACHAR)
  168.         {
  169.             if (sawmeta)
  170.                 putchar(METACHAR);
  171.             putchar(c);
  172.             sawmeta = 0;
  173.         }
  174.         else
  175.             sawmeta++;
  176.     }
  177.     exit(0);
  178. }
  179.  
  180. /* end of cookie.c */
  181.